/*
** ShpBrk20.c  -  this file contains methods for the 20-noded quadratic
**                Serendipity brick finite element shape.
**
**    The adopted numbering scheeme is shown below:
**
**                s
**                  ^
**                  |    (natural coord. system)
**                  |
**                  -----> r
**                 /
**                /
**               t
**
**                       19-------18------17
**                       +|              +|
**                      + |             + |
**                     12 |            11 |
**                    +   20          +   16
**                   +    |          +    |
**                  7-------6-------5     |
**                  |     |         |     |
**                  |    13------14-|-----15
**                  |    +          |    +
**                  8   +  front    4   +
**                  |  9   face     | 10
**                  | +             | +
**                  |+              |+
**                  1-------2-------3
**
**
**           Internal numbering:
**
**
**                       18-------17------16
**                       +|              +|
**                      + |             + |
**                     11 |            10 |
**                    +   19          +   15
**                   +    |          +    |
**                  6-------5-------4     |
**                  |     |         |     |
**                  |    12------13-|-----14
**                  |    +          |    +
**                  7   +           3   +
**                  |  8            |  9
**                  | +             | +
**                  |+              |+
**                  0-------1-------2
**
**
** --------------------------------------------------------------------------
**
** Entry Points:
**
** --------------------------------------------------------------------------
**
** void InitBRICK20( void )
**
**      Initializes sub-class NF_BRICK20.
**
** --------------------------------------------------------------------------
**
** static Telement_3d *NewBRICK20( void )
**
**      This method allocates memory for a given NF_BRICK20 element shape 
**      and returns a pointer to the new object.
**
** --------------------------------------------------------------------------
**
** static void ReadReseqBRICK20 ( int *reseq )
**
**      reseq    -  node numbering resequecing vector          (  in )
**
**      Reads node numbering resequecing vector NF_BRICK20 finite 
**      element shape class.
**
** --------------------------------------------------------------------------
**
** static void ReseqBRICK20 ( int *reseq )
**
**      reseq    -  node numbering resequecing vector          (  in )
**
**      Specifies node numbering resequecing for NF_BRICK20 finite 
**      element shape class.
**
** --------------------------------------------------------------------------
**
** static void GetReseqBRICK20 ( int *reseq )
**
**      reseq    -  node numbering resequecing vector          ( out )
**
**      Gets resequence vector for NF_BRICK20 finite element shape node 
**      numbering.
**
** --------------------------------------------------------------------------
**
** static void ConnectBRICK20 ( Telement_3d *shp,
**                              int    *connect )
**
**      shp      -  given element shape                        (  in )
**      connect  -  connectivity of the given element shape    ( out )
**
**      Returns connectivity of a given NF_BRICK20 finite element shape.
**
** --------------------------------------------------------------------------
**
** static void DerivMapBRICK20rst ( Telement_3d    *shp,
**                                  NatCoord  *gauss_rst, 
**                                  DerivNat  deriv_rst[20] )
**
**      shp           -   given element shape  (not used)      (  in )
**      gauss_rst     -   natural coords.                      (  in )
**      deriv_rst     -   partial derivative wrt r,s,t         ( out )
**
**      This routine  returns the  "map"  functions  derivatives  with
**      respect to  the natural  coordinates for a 20-noded hexahedron
**      solid finite element shape. The "map" function derivatives are
**      evaluated at the given natural coordinates. Numbering scheme is 
**      same as that given above.
**
** --------------------------------------------------------------------------
**
** static int  DimBRICK20 ( Telement_3d *shp )
**
**      shp          -  given element shape  (not used)        (  in )
**
**      Returns dimension number of NF_BRICK20 shape, ie. 3.
**
** --------------------------------------------------------------------------
**
** static void GaussTypeBRICK20 ( Telement_3d    *shp,
**                                GaussType *gauss_type )
**
**      shp        -  given element shape (not used)             (  in )
**      GaussType  -  returned Gauss integration type            ( out )
**
**      Returns the Gauss integration type which is consistent with 
**      this element shape, i.e., CUBE_QUADRATURE.
**
** --------------------------------------------------------------------------
**
** static int  GetFirstEdgeBRICK20 ( Telement_3d    *shp,
**                                   int       *num_verts,
**                                   int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number edge verts                          ( out )
**      connect    -  edge connectivity                          ( out )
**
**      Gets no. of verts and connectivity of first edge of given shape.
**      The verts are returned in sequential order along the edge.
**
** --------------------------------------------------------------------------
**
** static int  GetNextEdgeBRICK20 ( Telement_3d    *shp,
**                                  int       *num_verts,
**                                  int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number edge verts                          ( out )
**      connect    -  edge connectivity                          ( out )
**
**      Gets no. of verts and connectivity of next edge of given shape.  
**      The verts are returned in sequential order along the edge.
**      If there is no other edge returns a false (0) status.
**      Otherwise, it returns a true (1) status.
**
** --------------------------------------------------------------------------
**
** static int  GetFirstFaceBRICK20 ( Telement_3d    *shp,
**                                   int       *num_verts,
**                                   int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number face verts                          ( out )
**      connect    -  face connectivity                          ( out )
**
**      Gets no. of verts and connectivity of first face of given shape.
**      The verts are returned in sequential order along the face.
**
** --------------------------------------------------------------------------
**
** static int  GetNextFaceBRICK20 ( Telement_3d    *shp,
**                                  int       *num_verts,
**                                  int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      num_verts  -  number face verts                          ( out )
**      connect    -  face connectivity                          ( out )
**
**      Gets no. of verts and connectivity of next face of given shape.  
**      The verts are returned in sequential order along the face.
**      If there is no other face returns a false (0) status.
**      Otherwise, it returns a true (1) status.
**
** --------------------------------------------------------------------------
**
** static int  GetShpEdgeBRICK20 ( Telement_3d    *shp,
**                                 int       corners[],
**                                 AuxShapeType *type,
**                                 int       *num_nodes,
**                                 int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      corners    -  corners of edge                            (  in )
**      type       -  returned edge shape type                   ( out )
**      num_nodes  -  number edge nodes                          ( out )
**      connect    -  edge connectivity                          ( out )
**
**      Gets shape type, no. of nodes, and connectivity of an edge of 
**      given shape for a given pair of corner nodes.
**      The returned edge shape type is LINE3.
**
** --------------------------------------------------------------------------
**
** static int  GetShpFaceBRICK20 ( Telement_3d    *shp,
**                                 int       corners[],
**                                 AuxShapeType *type,
**                                 int       *num_nodes,
**                                 int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      corners    -  corners of face                            (  in )
**      type       -  returned face shape type                   ( out )
**      num_nodes  -  number face nodes                          ( out )
**      connect    -  face connectivity                          ( out )
**
**      Gets shape type, no. of nodes, and connectivity of a face of 
**      given shape for a given triple of corner nodes.
**      The returned face shape type is QUAD8.
**
** --------------------------------------------------------------------------
**
** static void GetShpDomainBRICK20 ( Telement_3d    *shp,
**                                   AuxShapeType *type,
**                                   int       *num_nodes,
**                                   int       connect[] )
**
**      shp        -  given element shape                        (  in )
**      type       -  returned domain shape type                 ( out )
**      num_nodes  -  number domain nodes                        ( out )
**      connect    -  domain connectivity                        ( out )
**
**      Gets shape type, no. of nodes, and connectivity of given shape.
**      The returned shape type is NF_BRICK20 and the number of domain nodes
**      is 20.
**
** --------------------------------------------------------------------------
**
** static void MakeBRICK20 ( Telement_3d *shp,
**                           int    *connect )
**
**      shp      -  given element shape                        (  in )
**      connect  -  connectivity of the given element          (  in )
**
**      Makes a NF_BRICK20 element shape of given connectivity.
**      Connectivity is ordered according to the class node 
**      resequencing data.
**
** --------------------------------------------------------------------------
**
** static void MakeDefaultBRICK20 ( Telement_3d *shp,
**                                  int    *connect )
**
**      shp      -  given element shape                        (  in )
**      connect  -  connectivity of the given element          (  in )
**
**      Makes a NF_BRICK20 element shape of given connectivity.
**      The connectivity is assumed in the default class sequence.
**
** --------------------------------------------------------------------------
**
** static void MapFuncBRICK20 ( Telement_3d    *shp,
**                              NatCoord  *nat_coord, 
**                              ShapeVal  *shape )
**
**      shp          -  given element shape (not used)         (  in )
**      nat_coord   -   natural coords.                        (  in )
**      shape       -   shape funcs. evaluated at given pt.    ( out )
**
**      This routine returns the "map" functions for a  20-noded solid
**      hexahedron  element shape.  The "map" functions are  evaluated
**      at the given natural coordinates. 
**
** --------------------------------------------------------------------------
**
** static void NodalNatCoordBRICK20 ( Telement_3d    *shp,
**                                    NatCoord  *coord )
**
**      shp         -   given element shape                    (  in )
**      coords      -   natural coordinates of its nodes       ( out )
**
**      Returns shape natural nodal coordinates.
**
** --------------------------------------------------------------------------
**
** static int  NumNodesBRICK20 ( Telement_3d *shp )
**
**      shp          -  given element shape  (not used)        (  in )
**
**      Returns number of nodes in a 20-noded brick shape, ie. 20.
**
** --------------------------------------------------------------------------
**
** static int  ReadBRICK20 ( Telement_3d *shp, int *conn )
**
**      shp           -  Given element shape                   (  in )
**      conn          -  Connectivity of element               (  in )
**      
**      This method reads nodal connectivity  data of a given "NF_BRICK20" 
**      shape element.
**
** --------------------------------------------------------------------------
**
** version: 1-000
**
** history: Created:   30-Jul-96   Luiz Fernando Martha
**              Stolen from Femoop and modified.
**
**          Modified:  19-Oct-98   Joaquim Bento Cavalcante Neto
**              Modified some methods to agree with other shape modules.
**
** Modified:  Novem/2000 - Antonio Miranda (amiranda)
**      Changed the input of read method (FILE -> int *conn)
**
** --------------------------------------------------------------------------
*/

/* Global variables and symbols           */

#define _SHPBRICK20_C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "shp.h"


/*  Local variables and symbols  */

/*
** --------------------------------------------------------------------------
** Local data structures:
**
*/

typedef struct _databrick20 {
   int   node[20];    /* element node indices */
} DataBRICK20;

/* Resequence node numbering vector:
 */
static int  rs[20] = {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 
                       10, 11, 12, 13, 14, 15, 16, 17, 18, 19  };

/* Edge and Face lists:
 */
#define NEDGES  12
static int curr_edge = 0;;
static int el[NEDGES][3] =  { {   0,  1,  2  },
                              {   2,  3,  4  },
                              {   4,  5,  6  },
                              {   6,  7,  0  },
                              {   0,  8, 12  },
                              {   2,  9, 14  },
                              {   4, 10, 16  },
                              {   6, 11, 18  },
                              {  12, 13, 14  },
                              {  14, 15, 16  },
                              {  16, 17, 18  },
                              {  18, 19, 12  } };

#define NFACES  6
static int curr_face = 0;;
static int fl[NFACES][8] =  { {   0,  1,  2,  3,  4,  5,  6,  7  },
                              {   0,  8, 12, 13, 14,  9,  2,  1  },
                              {   2,  9, 14, 15, 16, 10,  4,  3  },
                              {   4, 10, 16, 17, 18, 11,  6,  5  },
                              {   6, 11, 18, 19, 12,  8,  0,  7  },
                              {  12, 19, 18, 17, 16, 15, 14, 13  } }; 

/* Use quadrature 2x2x2 = 8 gauss point */
static int num_gauss_point = 8;
static NatCoord gauss_rst[8] = {
  {+0.577350269189626, +0.577350269189626, +0.577350269189626},
  {-0.577350269189626, +0.577350269189626, +0.577350269189626},
  {+0.577350269189626, -0.577350269189626, +0.577350269189626},
  {-0.577350269189626, -0.577350269189626, +0.577350269189626},
  {+0.577350269189626, +0.577350269189626, -0.577350269189626},
  {-0.577350269189626, +0.577350269189626, -0.577350269189626},
  {+0.577350269189626, -0.577350269189626, -0.577350269189626},
  {-0.577350269189626, -0.577350269189626, -0.577350269189626}
};
static GaussWgt gauss_wgt[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

static ShapeVal shape_rst[20][20];
static DerivNat deriv_rst[20][20];


/* Local entry points: */

static Telement_3d *NewBRICK20       ( void );
static void ReadReseqBRICK20    ( int * );
static void ReseqBRICK20        ( int * );
static void GetReseqBRICK20     ( int * );
static void ConnectBRICK20      ( Telement_3d *, int * );
static void DerivMapBRICK20rst  ( Telement_3d *, NatCoord *, DerivNat[]  );
static int  DimBRICK20          ( Telement_3d * );
static void MapFuncBRICK20_i    ( Telement_3d *, int , ShapeVal ** );

static int    NumGaussPoint       (void);
static void   DerivMapBRICK20_i   ( Telement_3d *, int, DerivNat **);
static double GaussWgtBRICK20_i   ( Telement_3d *shp, int i);

static int  GetFirstEdgeBRICK20 ( Telement_3d *, int *, int [] );
static int  GetNextEdgeBRICK20  ( Telement_3d *, int *, int [] );
static int  GetFirstFaceBRICK20 ( Telement_3d *, int *, int [] );
static int  GetNextFaceBRICK20  ( Telement_3d *, int *, int [] );
static int  GetShpEdgeBRICK20   ( Telement_3d *, int [], AuxShapeType *, int *, int [] );
static int  GetShpFaceBRICK20   ( Telement_3d *, int [], AuxShapeType *, int *, int [] );
static void GetShpDomainBRICK20 ( Telement_3d *, ShapeType *, int *, int[] );
static void MakeBRICK20         ( Telement_3d *, int * );
static void MakeDefaultBRICK20  ( Telement_3d *, int * );
static void MapFuncBRICK20      ( Telement_3d *, NatCoord *, ShapeVal * );
static void NodalNatCoordBRICK20( Telement_3d *, NatCoord * );
static int  NumNodesBRICK20     ( Telement_3d * );
static int  ReadBRICK20         ( Telement_3d *, int * );







/* Public Entry Points: */


/* ============================= InitBRICK20 ================================ */

void InitBRICK20( void )
{
   shape_class[NF_BRICK20].New                   =    NewBRICK20;
   shape_class[NF_BRICK20].readresequence        =    ReadReseqBRICK20;
   shape_class[NF_BRICK20].resequence            =    ReseqBRICK20;
   shape_class[NF_BRICK20].getresequence         =    GetReseqBRICK20;
   shape_class[NF_BRICK20].connectivity          =    ConnectBRICK20;
   shape_class[NF_BRICK20].shapefunc             =    MapFuncBRICK20;
   shape_class[NF_BRICK20].shapefunc_i           =    MapFuncBRICK20_i;

   shape_class[NF_BRICK20].derivmaprst           =    DerivMapBRICK20rst;
   shape_class[NF_BRICK20].derivshprst           =    DerivMapBRICK20rst;
   shape_class[NF_BRICK20].derivmap_i            =    DerivMapBRICK20_i;
   shape_class[NF_BRICK20].derivshp_i            =    DerivMapBRICK20_i;

   shape_class[NF_BRICK20].derivxyz              =    shp_derivXYZ;
   shape_class[NF_BRICK20].numgausspoint         =    NumGaussPoint;
   shape_class[NF_BRICK20].bmatrix               =    shp_BMatrix;
   shape_class[NF_BRICK20].gaussw_i              =    GaussWgtBRICK20_i;

   shape_class[NF_BRICK20].derivxyz              =    shp_derivxyzsolid;
   shape_class[NF_BRICK20].dim                   =    DimBRICK20;
   shape_class[NF_BRICK20].free                  =    shp_freeshape;
   shape_class[NF_BRICK20].gausstonode           =    shp_gausstonode;

   shape_class[NF_BRICK20].dim                   =    DimBRICK20;
   shape_class[NF_BRICK20].free                  =    shp_freeshape;
   shape_class[NF_BRICK20].gausstonode           =    shp_gausstonode;
   shape_class[NF_BRICK20].jacobian              =    shp_jacobian;

   //shape_class[NF_BRICK20].gausstype             =    GaussTypeBRICK20;
   shape_class[NF_BRICK20].getfirstedge          =    GetFirstEdgeBRICK20;
   shape_class[NF_BRICK20].getnextedge           =    GetNextEdgeBRICK20;
   shape_class[NF_BRICK20].getfirstface          =    GetFirstFaceBRICK20;
   shape_class[NF_BRICK20].getnextface           =    GetNextFaceBRICK20;
   shape_class[NF_BRICK20].getshpedge            =    GetShpEdgeBRICK20;
   shape_class[NF_BRICK20].getshpface            =    GetShpFaceBRICK20;
   shape_class[NF_BRICK20].getshpdomain          =    GetShpDomainBRICK20;
   shape_class[NF_BRICK20].getverts              =    ConnectBRICK20;
   shape_class[NF_BRICK20].isinterface           =    shp_isinterface;
   shape_class[NF_BRICK20].jacobian              =    shp_jacobiansolid;
   shape_class[NF_BRICK20].localsys              =    shp_localsyssolid;
   shape_class[NF_BRICK20].make                  =    MakeBRICK20;
   shape_class[NF_BRICK20].makedefault           =    MakeDefaultBRICK20;
   shape_class[NF_BRICK20].mapfunc               =    MapFuncBRICK20;
   shape_class[NF_BRICK20].nodalnatcoord         =    NodalNatCoordBRICK20;
   shape_class[NF_BRICK20].nodetovertex          =    shp_nodetovertex;
   shape_class[NF_BRICK20].nummapnodes           =    NumNodesBRICK20;
   shape_class[NF_BRICK20].numshpnodes           =    NumNodesBRICK20;
   shape_class[NF_BRICK20].numverts              =    NumNodesBRICK20;
   shape_class[NF_BRICK20].print                 =    shp_printshape;
   shape_class[NF_BRICK20].read                  =    ReadBRICK20;

   int i;
   for (i = 0; i < num_gauss_point; i++)
   {
     MapFuncBRICK20 (NULL, &gauss_rst[i], shape_rst[i]);
     DerivMapBRICK20rst ( NULL, &gauss_rst[i], deriv_rst[i]);
   }
}


/* ============================== NewBRICK20 ================================ */

static Telement_3d *NewBRICK20 ( void )
{
   Telement_3d        *shp;
   DataBRICK20   *dat;

   shp = (Telement_3d *)calloc( 1, sizeof(Telement_3d) );

   dat = (DataBRICK20 *)calloc( 1, sizeof(DataBRICK20) );

   shp->type = NF_BRICK20;

   return( shp );
}


/* =========================== ReadReseqBRICK20 ============================= */

static void ReadReseqBRICK20 ( int *reseq )
{
   int i;

   for (i=0;i<20;i++)
      rs[i] = reseq[i] - 1;
}


/* ============================= ReseqBRICK20 =============================== */

static void ReseqBRICK20 ( int *reseq )
{
   int i;

   for( i=0; i<20; i++ )
    rs[i] = reseq[i];
}


/* ============================ GetReseqBRICK20 ============================= */

static void GetReseqBRICK20 ( int *reseq )
{
   int i;

   for( i=0; i<20; i++ )
    reseq[i] = rs[i];
}


/* =============================== ConnectBRICK20 =========================== */

static void ConnectBRICK20 ( Telement_3d *shp,
                             int    *connect )
{
   connect[ 0] = shp->inc[ 0];
   connect[ 1] = shp->inc[ 1];
   connect[ 2] = shp->inc[ 2];
   connect[ 3] = shp->inc[ 3];
   connect[ 4] = shp->inc[ 4];
   connect[ 5] = shp->inc[ 5];
   connect[ 6] = shp->inc[ 6];
   connect[ 7] = shp->inc[ 7];
   connect[ 8] = shp->inc[ 8];
   connect[ 9] = shp->inc[ 9];
   connect[10] = shp->inc[10];
   connect[11] = shp->inc[11];
   connect[12] = shp->inc[12];
   connect[13] = shp->inc[13];
   connect[14] = shp->inc[14];
   connect[15] = shp->inc[15];
   connect[16] = shp->inc[16];
   connect[17] = shp->inc[17];
   connect[18] = shp->inc[18];
   connect[19] = shp->inc[19];
}

/* ============================= MapFuncBRICK20 ============================= */

static void MapFuncBRICK20 ( Telement_3d   *shp,
                             NatCoord *nat_coord, 
                             ShapeVal *shape )
{
   double   r, s, t, r2, s2, t2;

   ignore (shp);

   r = nat_coord->r;
   s = nat_coord->s;
   t = nat_coord->t;
 
   r2 = r*r;
   s2 = s*s;
   t2 = t*t;
 
   shape[ 0] = 0.125 * (1.0-r) * (1.0-s) * (1.0+t)*(-r-s+t-2.0);
   shape[ 1] = 0.250 * (1.0-r2)* (1.0-s) * (1.0+t);
   shape[ 2] = 0.125 * (1.0+r) * (1.0-s) * (1.0+t)*(r-s+t-2.0);
   shape[ 3] = 0.250 * (1.0+r) * (1.0-s2)* (1.0+t);
   shape[ 4] = 0.125 * (1.0+r) * (1.0+s) * (1.0+t)*(r+s+t-2.0);
   shape[ 5] = 0.250 * (1.0-r2)* (1.0+s) * (1.0+t);
   shape[ 6] = 0.125 * (1.0-r) * (1.0+s) * (1.0+t)*(-r+s+t-2.0);
   shape[ 7] = 0.250 * (1.0-r) * (1.0-s2)* (1.0+t);
   shape[ 8] = 0.250 * (1.0-r) * (1.0-s) * (1.0-t2);
   shape[ 9] = 0.250 * (1.0+r) * (1.0-s) * (1.0-t2);
   shape[10] = 0.250 * (1.0+r) * (1.0+s) * (1.0-t2);
   shape[11] = 0.250 * (1.0-r) * (1.0+s) * (1.0-t2);
   shape[12] = 0.125 * (1.0-r) * (1.0-s) * (1.0-t)*(-r-s-t-2.0);
   shape[13] = 0.250 * (1.0-r2)* (1.0-s) * (1.0-t);
   shape[14] = 0.125 * (1.0+r) * (1.0-s) * (1.0-t)*(r-s-t-2.0);
   shape[15] = 0.250 * (1.0+r) * (1.0-s2)* (1.0-t);
   shape[16] = 0.125 * (1.0+r) * (1.0+s) * (1.0-t)*(r+s-t-2.0);
   shape[17] = 0.250 * (1.0-r2)* (1.0+s) * (1.0-t);
   shape[18] = 0.125 * (1.0-r) * (1.0+s) * (1.0-t)*(-r+s-t-2.0);
   shape[19] = 0.250 * (1.0-r) * (1.0-s2)* (1.0-t);
}

/* ============================= MapFuncBRICK20_i ============================= */

static void MapFuncBRICK20_i ( Telement_3d   *shp, int i, ShapeVal **shape )
{
  if (i < 0 || i > num_gauss_point)
  {
    *shape = NULL;
    return;
  }
  *shape = shape_rst[i];
}


/* ========================== NodalNatCoordBRICK20 ========================== */

static void NodalNatCoordBRICK20 ( Telement_3d    *shp,
                                   NatCoord  *coord )
{
   ignore (shp);

   coord[ 0].r = -1.0; coord[ 0].s = -1.0; coord[ 0].t =  1.0;
   coord[ 1].r =  0.0; coord[ 1].s = -1.0; coord[ 1].t =  1.0;
   coord[ 2].r =  1.0; coord[ 2].s = -1.0; coord[ 2].t =  1.0;
   coord[ 3].r =  1.0; coord[ 3].s =  0.0; coord[ 3].t =  1.0;
   coord[ 4].r =  1.0; coord[ 4].s =  1.0; coord[ 4].t =  1.0;
   coord[ 5].r =  0.0; coord[ 5].s =  1.0; coord[ 5].t =  1.0;
   coord[ 6].r = -1.0; coord[ 6].s =  1.0; coord[ 6].t =  1.0;
   coord[ 7].r = -1.0; coord[ 7].s =  0.0; coord[ 7].t =  1.0;

   coord[ 8].r = -1.0; coord[ 8].s = -1.0; coord[ 8].t =  0.0;
   coord[ 9].r =  1.0; coord[ 9].s = -1.0; coord[ 9].t =  0.0;
   coord[10].r =  1.0; coord[10].s =  1.0; coord[10].t =  0.0;
   coord[11].r = -1.0; coord[11].s =  1.0; coord[11].t =  0.0;

   coord[12].r = -1.0; coord[12].s = -1.0; coord[12].t = -1.0;
   coord[13].r =  0.0; coord[13].s = -1.0; coord[13].t = -1.0;
   coord[14].r =  1.0; coord[14].s = -1.0; coord[14].t = -1.0;
   coord[15].r =  1.0; coord[15].s =  0.0; coord[15].t = -1.0;
   coord[16].r =  1.0; coord[16].s =  1.0; coord[16].t = -1.0;
   coord[17].r =  0.0; coord[17].s =  1.0; coord[17].t = -1.0;
   coord[18].r = -1.0; coord[18].s =  1.0; coord[18].t = -1.0;
   coord[19].r = -1.0; coord[19].s =  0.0; coord[19].t = -1.0;
}


/* ========================== DerivMapBRICK20rst ============================ */

static void DerivMapBRICK20rst ( Telement_3d   *shp,
                                 NatCoord *gauss_rst,
                                 DerivNat deriv_rst[20] )
{
   double  r, s, t, r2, s2, t2;

   ignore (shp);

   r = gauss_rst->r;
   s = gauss_rst->s;
   t = gauss_rst->t;

   r2 = r*r;
   s2 = s*s;
   t2 = t*t;

   deriv_rst[ 0].r = -0.125 * (1.0-s) * (1.0+t) * (-2.0*r-s+t-1.0);
   deriv_rst[ 1].r = -0.500 * r * (1.0-s) * (1.0+t);
   deriv_rst[ 2].r =  0.125 * (1.0-s) * (1.0+t) * (2.0*r-s+t-1.0);
   deriv_rst[ 3].r =  0.250 * (1.0-s2) * (1.0+t);
   deriv_rst[ 4].r =  0.125 * (1.0+s) * (1.0+t) * (2.0*r+s+t-1.0);
   deriv_rst[ 5].r = -0.500 * r * (1.0+s) * (1.0+t);
   deriv_rst[ 6].r = -0.125 * (1.0+s) * (1.0+t) * (-2.0*r+s+t-1.0);
   deriv_rst[ 7].r = -0.250 * (1.0-s2) * (1.0+t);
   deriv_rst[ 8].r = -0.250 * (1.0-s) * (1.0-t2);
   deriv_rst[ 9].r =  0.250 * (1.0-s) * (1.0-t2);
   deriv_rst[10].r =  0.250 * (1.0+s) * (1.0-t2);
   deriv_rst[11].r = -0.250 * (1.0+s) * (1.0-t2);
   deriv_rst[12].r = -0.125 * (1.0-s) * (1.0-t) * (-2.0*r-s-t-1.0);
   deriv_rst[13].r = -0.500 * r * (1.0-s) * (1.0-t);
   deriv_rst[14].r =  0.125 * (1.0-s) * (1.0-t) * (2.0*r-s-t-1.0);
   deriv_rst[15].r =  0.250 * (1.0-s2) * (1.0-t);
   deriv_rst[16].r =  0.125 * (1.0+s) * (1.0-t) * (2.0*r+s-t-1.0);
   deriv_rst[17].r = -0.500 * r * (1.0+s) * (1.0-t);
   deriv_rst[18].r = -0.125 * (1.0+s) * (1.0-t) * (-2.0*r+s-t-1.0);
   deriv_rst[19].r = -0.250 * (1.0-s2) * (1.0-t);

   deriv_rst[ 0].s = -0.125 * (1.0-r) * (1.0+t) * (-r-2.0*s+t-1.0);
   deriv_rst[ 1].s = -0.250 * (1.0-r2) * (1.0+t);
   deriv_rst[ 2].s = -0.125 * (1.0+r) * (1.0+t) * (r-2.0*s+t-1.0);
   deriv_rst[ 3].s = -0.500 * (1.0+r) * s * (1.0+t);
   deriv_rst[ 4].s =  0.125 * (1.0+r) * (1.0+t) * (r+2.0*s+t-1.0);
   deriv_rst[ 5].s =  0.250 * (1.0-r2) * (1.0+t);
   deriv_rst[ 6].s =  0.125 * (1.0-r) * (1.0+t) * (-r+2.0*s+t-1.0);
   deriv_rst[ 7].s = -0.500 * (1.0-r) * s * (1.0+t);
   deriv_rst[ 8].s = -0.250 * (1.0-r) * (1-t2);
   deriv_rst[ 9].s = -0.250 * (1.0+r) * (1.0-t2);
   deriv_rst[10].s =  0.250 * (1.0+r) * (1.0-t2);
   deriv_rst[11].s =  0.250 * (1.0-r) * (1.0-t2);
   deriv_rst[12].s = -0.125 * (1.0-r) * (1.0-t) * (-r-2.0*s-t-1.0);
   deriv_rst[13].s = -0.250 * (1.0-r2) * (1.0-t);
   deriv_rst[14].s = -0.125 * (1.0+r) * (1.0-t) * (r-2.0*s-t-1.0);
   deriv_rst[15].s = -0.500 * (1.0+r) * s * (1.0-t);
   deriv_rst[16].s =  0.125 * (1.0+r) * (1.0-t) * (r+2.0*s-t-1.0);
   deriv_rst[17].s =  0.250 * (1.0-r2) * (1.0-t);
   deriv_rst[18].s =  0.125 * (1.0-r) * (1.0-t) * (-r+2.0*s-t-1.0);
   deriv_rst[19].s = -0.500 * (1.0-r) * s * (1.0-t);

   deriv_rst[ 0].t =  0.125 * (1.0-r) * (1.0-s) * (-r-s+2.0*t-1.0);
   deriv_rst[ 1].t =  0.250 * (1.0-r2) * (1.0-s);
   deriv_rst[ 2].t =  0.125 * (1.0+r) * (1.0-s) * (r-s+2.0*t-1.0);
   deriv_rst[ 3].t =  0.250 * (1.0+r) * (1.0-s2);
   deriv_rst[ 4].t =  0.125 * (1.0+r) * (1.0+s) * (r+s+2.0*t-1.0);
   deriv_rst[ 5].t =  0.250 * (1.0-r2) * (1.0+s);
   deriv_rst[ 6].t =  0.125 * (1.0-r) * (1.0+s) * (-r+s+2.0*t-1.0);
   deriv_rst[ 7].t =  0.250 * (1.0-r) * (1.0-s2);
   deriv_rst[ 8].t = -0.500 * (1.0-r) * (1.0-s) * t;
   deriv_rst[ 9].t = -0.500 * (1.0+r) * (1.0-s) * t;
   deriv_rst[10].t = -0.500 * (1.0+r) * (1.0+s) * t;
   deriv_rst[11].t = -0.500 * (1.0-r) * (1.0+s) * t;
   deriv_rst[12].t = -0.125 * (1.0-r) * (1.0-s) * (-r-s-2.0*t-1.0);
   deriv_rst[13].t = -0.250 * (1.0-r2) * (1.0-s);
   deriv_rst[14].t = -0.125 * (1.0+r) * (1.0-s) * (r-s-2.0*t-1.0);
   deriv_rst[15].t = -0.250 * (1.0+r) * (1.0-s2);
   deriv_rst[16].t = -0.125 * (1.0+r) * (1.0+s) * (r+s-2.0*t-1.0);
   deriv_rst[17].t = -0.250 * (1.0-r2) * (1.0+s);
   deriv_rst[18].t = -0.125 * (1.0-r) * (1.0+s) * (-r+s-2.0*t-1.0);
   deriv_rst[19].t = -0.250 * (1.0-r) * (1.0-s2);
}





/* =============================== DimBRICK20 =============================== */

static int DimBRICK20( Telement_3d *shp )
{
   ignore (shp);

   return ( 3 );
}


/* ============================== NumGaussPoint =========================== */
static int NumGaussPoint (void)
{
  return (num_gauss_point);
}


/* ============================== DerivMapBRICK20_i =========================== */
static void DerivMapBRICK20_i  ( Telement_3d *shp, int i, DerivNat **ptr)
{
  if (i < 0 || i > 19)
  {
    ptr = NULL;
    return;
  }
  *ptr = deriv_rst[i];
}


/* ============================== GaussWgtBRICK20_i =========================== */
static double GaussWgtBRICK20_i  ( Telement_3d *shp, int i)
{
  if (i < 0 || i > 7)
    return 0.0;

  return (gauss_wgt[i]);
}


/* ============================== GaussTypeBRICK20 ========================== */


#if 0
static void GaussTypeBRICK20 ( Telement_3d    *shp,
                               GaussType *gauss_type )
{
   ignore (shp);

   *gauss_type = CUBE_QUADRATURE;
}
#endif


/* ============================= GetFirstEdgeBRICK20 ======================== */

static int  GetFirstEdgeBRICK20 ( Telement_3d    *shp,
                                  int       *num_verts,
                                  int       connect[] )
{

   *num_verts = 3;
   curr_edge = 0;

   connect[0] = shp->inc[el[curr_edge][0]];
   connect[1] = shp->inc[el[curr_edge][1]];
   connect[2] = shp->inc[el[curr_edge][2]];
   return( 1 );
}


/* ============================= GetNextEdgeBRICK20 ========================= */

static int  GetNextEdgeBRICK20 ( Telement_3d    *shp,
                                 int       *num_verts,
                                 int       connect[] )
{
   *num_verts = 3;
   curr_edge++;

   if( curr_edge >= NEDGES )
    return( 0 );

   connect[0] = shp->inc[el[curr_edge][0]];
   connect[1] = shp->inc[el[curr_edge][1]];
   connect[2] = shp->inc[el[curr_edge][2]];
   return( 1 );
}


/* ============================= GetFirstFaceBRICK20 ======================== */

static int  GetFirstFaceBRICK20 ( Telement_3d    *shp,
                                  int       *num_verts,
                                  int       connect[] )
{

   *num_verts = 8;
   curr_face = 0;

   connect[0] = shp->inc[fl[curr_face][0]];
   connect[1] = shp->inc[fl[curr_face][1]];
   connect[2] = shp->inc[fl[curr_face][2]];
   connect[3] = shp->inc[fl[curr_face][3]];
   connect[4] = shp->inc[fl[curr_face][4]];
   connect[5] = shp->inc[fl[curr_face][5]];
   connect[6] = shp->inc[fl[curr_face][6]];
   connect[7] = shp->inc[fl[curr_face][7]];
   return( 1 );
}


/* ============================= GetNextFaceBRICK20 ========================= */

static int  GetNextFaceBRICK20 ( Telement_3d    *shp,
                                 int       *num_verts,
                                 int       connect[] )
{
   *num_verts = 8;
   curr_face++;

   if( curr_face >= NFACES )
    return( 0 );

   connect[0] = shp->inc[fl[curr_face][0]];
   connect[1] = shp->inc[fl[curr_face][1]];
   connect[2] = shp->inc[fl[curr_face][2]];
   connect[3] = shp->inc[fl[curr_face][3]];
   connect[4] = shp->inc[fl[curr_face][4]];
   connect[5] = shp->inc[fl[curr_face][5]];
   connect[6] = shp->inc[fl[curr_face][6]];
   connect[7] = shp->inc[fl[curr_face][7]];
   return( 1 );
}


/* ============================= GetShpEdgeBRICK20 ========================== */

static int  GetShpEdgeBRICK20 ( Telement_3d    *shp,
                                int       corners[],
                                AuxShapeType *type,
                                int       *num_nodes,
                                int       connect[] )
{
   int          status = 0;

   *type = LINE3;
   *num_nodes = 3;

   if( corners[0] == shp->inc[0] )
   {
    connect[0] = shp->inc[0];
    if( corners[1] == shp->inc[6] )
    {
     connect[1] = shp->inc[7];
     connect[2] = shp->inc[6];
     status = 1;
    }
    else if( corners[1] == shp->inc[2] )
    {
     connect[1] = shp->inc[1];
     connect[2] = shp->inc[2];
     status = 1;
    }
    else if( corners[1] == shp->inc[12] )
    {
     connect[1] = shp->inc[8];
     connect[2] = shp->inc[12];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[2] )
   {
    connect[0] = shp->inc[2];
    if( corners[1] == shp->inc[0] )
    {
     connect[1] = shp->inc[1];
     connect[2] = shp->inc[0];
     status = 1;
    }
    else if( corners[1] == shp->inc[4] )
    {
     connect[1] = shp->inc[3];
     connect[2] = shp->inc[4];
     status = 1;
    }
    else if( corners[1] == shp->inc[14] )
    {
     connect[1] = shp->inc[9];
     connect[2] = shp->inc[14];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[4] )
   {
    connect[0] = shp->inc[4];
    if( corners[1] == shp->inc[2] )
    {
     connect[1] = shp->inc[3];
     connect[2] = shp->inc[2];
     status = 1;
    }
    else if( corners[1] == shp->inc[6] )
    {
     connect[1] = shp->inc[5];
     connect[2] = shp->inc[6];
     status = 1;
    }
    else if( corners[1] == shp->inc[16] )
    {
     connect[1] = shp->inc[10];
     connect[2] = shp->inc[16];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[6] )
   {
    connect[0] = shp->inc[6];
    if( corners[1] == shp->inc[4] )
    {
     connect[1] = shp->inc[5];
     connect[2] = shp->inc[4];
     status = 1;
    }
    else if( corners[1] == shp->inc[0] )
    {
     connect[1] = shp->inc[7];
     connect[2] = shp->inc[0];
     status = 1;
    }
    else if( corners[1] == shp->inc[18] )
    {
     connect[1] = shp->inc[11];
     connect[2] = shp->inc[18];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[12] )
   {
    connect[0] = shp->inc[12];
    if( corners[1] == shp->inc[18] )
    {
     connect[1] = shp->inc[19];
     connect[2] = shp->inc[18];
     status = 1;
    }
    else if( corners[1] == shp->inc[14] )
    {
     connect[1] = shp->inc[13];
     connect[2] = shp->inc[14];
     status = 1;
    }
    else if( corners[1] == shp->inc[0] )
    {
     connect[1] = shp->inc[8];
     connect[2] = shp->inc[0];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[14] )
   {
    connect[0] = shp->inc[14];
    if( corners[1] == shp->inc[12] )
    {
     connect[1] = shp->inc[13];
     connect[2] = shp->inc[12];
     status = 1;
    }
    else if( corners[1] == shp->inc[16] )
    {
     connect[1] = shp->inc[15];
     connect[2] = shp->inc[16];
     status = 1;
    }
    else if( corners[1] == shp->inc[2] )
    {
     connect[1] = shp->inc[9];
     connect[2] = shp->inc[2];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[16] )
   {
    connect[0] = shp->inc[16];
    if( corners[1] == shp->inc[14] )
    {
     connect[1] = shp->inc[15];
     connect[2] = shp->inc[14];
     status = 1;
    }
    else if( corners[1] == shp->inc[18] )
    {
     connect[1] = shp->inc[17];
     connect[2] = shp->inc[18];
     status = 1;
    }
    else if( corners[1] == shp->inc[4] )
    {
     connect[1] = shp->inc[10];
     connect[2] = shp->inc[4];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[18] )
   {
    connect[0] = shp->inc[18];
    if( corners[1] == shp->inc[16] )
    {
     connect[1] = shp->inc[17];
     connect[2] = shp->inc[16];
     status = 1;
    }
    else if( corners[1] == shp->inc[12] )
    {
     connect[1] = shp->inc[19];
     connect[2] = shp->inc[12];
     status = 1;
    }
    else if( corners[1] == shp->inc[6] )
    {
     connect[1] = shp->inc[11];
     connect[2] = shp->inc[6];
     status = 1;
    }
   }

   return( status );
}


/* ============================= GetShpFaceBRICK20 ========================== */

static int  GetShpFaceBRICK20 ( Telement_3d    *shp,
                                int       corners[],
                                AuxShapeType *type,
                                int       *num_nodes,
                                int       connect[] )
{
   int          status = 0;

   *type = QUAD8;
   *num_nodes = 8;

   if( corners[0] == shp->inc[0] )
   {
    connect[0] = shp->inc[0];
    if( (corners[1] == shp->inc[2]) && (corners[2] == shp->inc[6]) )
    {
     connect[1] = shp->inc[1];
     connect[2] = shp->inc[2];
     connect[3] = shp->inc[3];
     connect[4] = shp->inc[4];
     connect[5] = shp->inc[5];
     connect[6] = shp->inc[6];
     connect[7] = shp->inc[7];
     status = 1;
    }
    else if( (corners[1] == shp->inc[6]) && (corners[2] == shp->inc[12]) )
    {
     connect[1] = shp->inc[7];
     connect[2] = shp->inc[6];
     connect[3] = shp->inc[11];
     connect[4] = shp->inc[18];
     connect[5] = shp->inc[19];
     connect[6] = shp->inc[12];
     connect[7] = shp->inc[8];
     status = 1;
    }
    else if( (corners[1] == shp->inc[12]) && (corners[2] == shp->inc[2]) )
    {
     connect[1] = shp->inc[8];
     connect[2] = shp->inc[12];
     connect[3] = shp->inc[13];
     connect[4] = shp->inc[14];
     connect[5] = shp->inc[9];
     connect[6] = shp->inc[2];
     connect[7] = shp->inc[1];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[2] )
   {
    connect[0] = shp->inc[2];
    if( (corners[1] == shp->inc[4]) && (corners[2] == shp->inc[0]) )
    {
     connect[1] = shp->inc[3];
     connect[2] = shp->inc[4];
     connect[3] = shp->inc[5];
     connect[4] = shp->inc[6];
     connect[5] = shp->inc[7];
     connect[6] = shp->inc[0];
     connect[7] = shp->inc[1];
     status = 1;
    }
    else if( (corners[1] == shp->inc[0]) && (corners[2] == shp->inc[14]) )
    {
     connect[1] = shp->inc[1];
     connect[2] = shp->inc[0];
     connect[3] = shp->inc[8];
     connect[4] = shp->inc[12];
     connect[5] = shp->inc[13];
     connect[6] = shp->inc[14];
     connect[7] = shp->inc[9];
     status = 1;
    }
    else if( (corners[1] == shp->inc[14]) && (corners[2] == shp->inc[4]) )
    {
     connect[1] = shp->inc[9];
     connect[2] = shp->inc[14];
     connect[3] = shp->inc[15];
     connect[4] = shp->inc[16];
     connect[5] = shp->inc[10];
     connect[6] = shp->inc[4];
     connect[7] = shp->inc[3];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[4] )
   {
    connect[0] = shp->inc[4];
    if( (corners[1] == shp->inc[6]) && (corners[2] == shp->inc[2]) )
    {
     connect[1] = shp->inc[5];
     connect[2] = shp->inc[6];
     connect[3] = shp->inc[7];
     connect[4] = shp->inc[0];
     connect[5] = shp->inc[1];
     connect[6] = shp->inc[2];
     connect[7] = shp->inc[3];
     status = 1;
    }
    else if( (corners[1] == shp->inc[2]) && (corners[2] == shp->inc[16]) )
    {
     connect[1] = shp->inc[3];
     connect[2] = shp->inc[2];
     connect[3] = shp->inc[9];
     connect[4] = shp->inc[14];
     connect[5] = shp->inc[15];
     connect[6] = shp->inc[16];
     connect[7] = shp->inc[10];
     status = 1;
    }
    else if( (corners[1] == shp->inc[16]) && (corners[2] == shp->inc[6]) )
    {
     connect[1] = shp->inc[10];
     connect[2] = shp->inc[16];
     connect[3] = shp->inc[17];
     connect[4] = shp->inc[18];
     connect[5] = shp->inc[11];
     connect[6] = shp->inc[6];
     connect[7] = shp->inc[5];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[6] )
   {
    connect[0] = shp->inc[6];
    if( (corners[1] == shp->inc[0]) && (corners[2] == shp->inc[4]) )
    {
     connect[1] = shp->inc[7];
     connect[2] = shp->inc[0];
     connect[3] = shp->inc[1];
     connect[4] = shp->inc[2];
     connect[5] = shp->inc[3];
     connect[6] = shp->inc[4];
     connect[7] = shp->inc[5];
     status = 1;
    }
    else if( (corners[1] == shp->inc[4]) && (corners[2] == shp->inc[18]) )
    {
     connect[1] = shp->inc[5];
     connect[2] = shp->inc[4];
     connect[3] = shp->inc[10];
     connect[4] = shp->inc[16];
     connect[5] = shp->inc[17];
     connect[6] = shp->inc[18];
     connect[7] = shp->inc[11];
     status = 1;
    }
    else if( (corners[1] == shp->inc[18]) && (corners[2] == shp->inc[0]) )
    {
     connect[1] = shp->inc[11];
     connect[2] = shp->inc[18];
     connect[3] = shp->inc[19];
     connect[4] = shp->inc[12];
     connect[5] = shp->inc[8];
     connect[6] = shp->inc[0];
     connect[7] = shp->inc[7];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[12] )
   {
    connect[0] = shp->inc[12];
    if( (corners[1] == shp->inc[18]) && (corners[2] == shp->inc[14]) )
    {
     connect[1] = shp->inc[19];
     connect[2] = shp->inc[18];
     connect[3] = shp->inc[17];
     connect[4] = shp->inc[16];
     connect[5] = shp->inc[15];
     connect[6] = shp->inc[14];
     connect[7] = shp->inc[13];
     status = 1;
    }
    else if( (corners[1] == shp->inc[14]) && (corners[2] == shp->inc[0]) )
    {
     connect[1] = shp->inc[13];
     connect[2] = shp->inc[14];
     connect[3] = shp->inc[9];
     connect[4] = shp->inc[2];
     connect[5] = shp->inc[1];
     connect[6] = shp->inc[0];
     connect[7] = shp->inc[8];
     status = 1;
    }
    else if( (corners[1] == shp->inc[0]) && (corners[2] == shp->inc[18]) )
    {
     connect[1] = shp->inc[8];
     connect[2] = shp->inc[0];
     connect[3] = shp->inc[7];
     connect[4] = shp->inc[6];
     connect[5] = shp->inc[11];
     connect[6] = shp->inc[18];
     connect[7] = shp->inc[19];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[14] )
   {
    connect[0] = shp->inc[14];
    if( (corners[1] == shp->inc[12]) && (corners[2] == shp->inc[16]) )
    {
     connect[1] = shp->inc[13];
     connect[2] = shp->inc[12];
     connect[3] = shp->inc[19];
     connect[4] = shp->inc[18];
     connect[5] = shp->inc[17];
     connect[6] = shp->inc[16];
     connect[7] = shp->inc[15];
     status = 1;
    }
    else if( (corners[1] == shp->inc[16]) && (corners[2] == shp->inc[2]) )
    {
     connect[1] = shp->inc[15];
     connect[2] = shp->inc[16];
     connect[3] = shp->inc[10];
     connect[4] = shp->inc[4];
     connect[5] = shp->inc[3];
     connect[6] = shp->inc[2];
     connect[7] = shp->inc[9];
     status = 1;
    }
    else if( (corners[1] == shp->inc[2]) && (corners[2] == shp->inc[12]) )
    {
     connect[1] = shp->inc[9];
     connect[2] = shp->inc[2];
     connect[3] = shp->inc[1];
     connect[4] = shp->inc[0];
     connect[5] = shp->inc[8];
     connect[6] = shp->inc[12];
     connect[7] = shp->inc[13];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[16] )
   {
    connect[0] = shp->inc[16];
    if( (corners[1] == shp->inc[14]) && (corners[2] == shp->inc[18]) )
    {
     connect[1] = shp->inc[15];
     connect[2] = shp->inc[14];
     connect[3] = shp->inc[13];
     connect[4] = shp->inc[12];
     connect[5] = shp->inc[19];
     connect[6] = shp->inc[18];
     connect[7] = shp->inc[17];
     status = 1;
    }
    else if( (corners[1] == shp->inc[18]) && (corners[2] == shp->inc[4]) )
    {
     connect[1] = shp->inc[17];
     connect[2] = shp->inc[18];
     connect[3] = shp->inc[11];
     connect[4] = shp->inc[6];
     connect[5] = shp->inc[5];
     connect[6] = shp->inc[4];
     connect[7] = shp->inc[10];
     status = 1;
    }
    else if( (corners[1] == shp->inc[4]) && (corners[2] == shp->inc[14]) )
    {
     connect[1] = shp->inc[10];
     connect[2] = shp->inc[4];
     connect[3] = shp->inc[3];
     connect[4] = shp->inc[2];
     connect[5] = shp->inc[9];
     connect[6] = shp->inc[14];
     connect[7] = shp->inc[15];
     status = 1;
    }
   }
   else if( corners[0] == shp->inc[18] )
   {
    connect[0] = shp->inc[18];
    if( (corners[1] == shp->inc[16]) && (corners[2] == shp->inc[12]) )
    {
     connect[1] = shp->inc[17];
     connect[2] = shp->inc[16];
     connect[3] = shp->inc[15];
     connect[4] = shp->inc[14];
     connect[5] = shp->inc[13];
     connect[6] = shp->inc[12];
     connect[7] = shp->inc[19];
     status = 1;
    }
    else if( (corners[1] == shp->inc[12]) && (corners[2] == shp->inc[6]) )
    {
     connect[1] = shp->inc[19];
     connect[2] = shp->inc[12];
     connect[3] = shp->inc[8];
     connect[4] = shp->inc[0];
     connect[5] = shp->inc[7];
     connect[6] = shp->inc[6];
     connect[7] = shp->inc[11];
     status = 1;
    }
    else if( (corners[1] == shp->inc[6]) && (corners[2] == shp->inc[16]) )
    {
     connect[1] = shp->inc[11];
     connect[2] = shp->inc[6];
     connect[3] = shp->inc[5];
     connect[4] = shp->inc[4];
     connect[5] = shp->inc[10];
     connect[6] = shp->inc[16];
     connect[7] = shp->inc[17];
     status = 1;
    }
   }

   return( status );
}


/* ============================ GetShpDomainBRICK20 ========================= */

static void GetShpDomainBRICK20 ( Telement_3d    *shp,
                                  ShapeType *type,
                                  int       *num_nodes,
                                  int       connect[] )
{
   *type = NF_BRICK20;
   *num_nodes = 20;

   ConnectBRICK20( shp, connect );
}


/* ================================ MakeBRICK20 ============================= */

static void MakeBRICK20 ( Telement_3d *shp,
                          int    *connect )
{
   shp->inc[rs[ 0]] = connect[ 0];
   shp->inc[rs[ 1]] = connect[ 1];
   shp->inc[rs[ 2]] = connect[ 2];
   shp->inc[rs[ 3]] = connect[ 3];
   shp->inc[rs[ 4]] = connect[ 4];
   shp->inc[rs[ 5]] = connect[ 5];
   shp->inc[rs[ 6]] = connect[ 6];
   shp->inc[rs[ 7]] = connect[ 7];
   shp->inc[rs[ 8]] = connect[ 9];
   shp->inc[rs[ 9]] = connect[ 9];
   shp->inc[rs[10]] = connect[10];
   shp->inc[rs[11]] = connect[11];
   shp->inc[rs[12]] = connect[12];
   shp->inc[rs[13]] = connect[13];
   shp->inc[rs[14]] = connect[14];
   shp->inc[rs[15]] = connect[15];
   shp->inc[rs[16]] = connect[16];
   shp->inc[rs[17]] = connect[17];
   shp->inc[rs[18]] = connect[18];
   shp->inc[rs[19]] = connect[19];
}


/* ============================ MakeDefaultBRICK20 ========================== */

static void MakeDefaultBRICK20 ( Telement_3d *shp,
                                 int    *connect )
{
   shp->inc[ 0] = connect[ 0];
   shp->inc[ 1] = connect[ 1];
   shp->inc[ 2] = connect[ 2];
   shp->inc[ 3] = connect[ 3];
   shp->inc[ 4] = connect[ 4];
   shp->inc[ 5] = connect[ 5];
   shp->inc[ 6] = connect[ 6];
   shp->inc[ 7] = connect[ 7];
   shp->inc[ 8] = connect[ 9];
   shp->inc[ 9] = connect[ 9];
   shp->inc[10] = connect[10];
   shp->inc[11] = connect[11];
   shp->inc[12] = connect[12];
   shp->inc[13] = connect[13];
   shp->inc[14] = connect[14];
   shp->inc[15] = connect[15];
   shp->inc[16] = connect[16];
   shp->inc[17] = connect[17];
   shp->inc[18] = connect[18];
   shp->inc[19] = connect[19];
}






/* ============================ NumNodesBRICK20 ============================= */

static int NumNodesBRICK20( Telement_3d *shp )
{
   ignore (shp);

   return ( 20 );
}


/* ============================= ReadBRICK20 ================================ */

static int ReadBRICK20( Telement_3d *shp, int *conn )
{
   int i;

   for (i=0;i<20;i++) 
     shp->inc[rs[i]] = conn[i];

   return( TRUE );
}


/* =========================================================== End of File */
